package com.librelato.persistencia;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import com.librelato.bean.CentroCustoBean;
import com.librelato.bean.FornecedorBean;
import com.librelato.bean.ProdutoBean;
import com.librelato.bean.SolicitacaoBean;
import com.librelato.bean.TabelaPrecoBean;
import com.librelato.negocio.TabelaPrecoServico;
import com.librelato.persistencia.config.SQLConfiguracao;
import com.librelato.persistencia.enums.EnumCondicao;
import com.librelato.persistencia.interfaces.IProdutoDao;
import com.librelato.util.Ferramentas;

public class ProdutoDao<P extends ProdutoBean> extends DaoGenerico<P> implements
		IProdutoDao<P> {

	@Override
	public String procuraPorParam(String tabela, String campo, String valor,
			EnumCondicao condicao) {
		return null;
	}

	public void editar(P p) throws Exception {
	};

	public void excluir(P p) throws Exception {
	};

	@Override
	public P salvar(P p) {
		return null;
	}

	@Override
	public void preSalvar(P p) {

	}

	@SuppressWarnings("unchecked")
	@Override
	public List<P> buscaProdutos(P p) throws Exception {
		conn = null;
		ps = null;
		rs = null;
		query = null;
		int psAux = 0;
		List<P> listaProd = new ArrayList<P>();
		P produto;
		try {
			conn = GerenciadorConexao.getConexao();

			if ((!"".equals(p.getCodigo()) && p.getCodigo() != null)
					|| (!"".equals(p.getDescricao()) && p.getDescricao() != null)
					|| (!"".equals(p.getGrupo()) && p.getGrupo() != null)
					|| (!"".equals(p.getGrupoDesc()))
					&& p.getGrupoDesc() != null) {

				query = SQLConfiguracao.getInstance().getValor(
						"localiza_produtos");

				if (p.getCodigo() != null && !"".equals(p.getCodigo())) {
					query += " AND UPPER(B1_COD) LIKE ?";
				}
				if (p.getDescricao() != null && !"".equals(p.getDescricao())) {
					query += " AND UPPER(B1_DESC) LIKE ?";
				}
				if (p.getGrupo() != null && !"".equals(p.getGrupo())) {
					query += " AND UPPER(B1_GRUPO) LIKE ?";
				}
				if (p.getGrupoDesc() != null && !"".equals(p.getGrupoDesc())) {
					query += " AND UPPER(BM_DESC) LIKE ?";
				}

				query += " LEFT JOIN ZZ2010 ON ZZ2_PRODUT = B1_COD AND ZZ2010.D_E_L_E_T_ <> '*'";

				if (p.getFilial() != null && !"".equals(p.getFilial())) {
					query += " AND ZZ2_FILIAL = ?";
				}

				ps = conn.prepareStatement(query);

				if (p.getCodigo() != null && !"".equals(p.getCodigo())) {
					psAux++;
					ps.setString(psAux, p.getCodigo().toUpperCase() + "%%");
				}
				if (p.getDescricao() != null && !"".equals(p.getDescricao())) {
					psAux++;
					ps.setString(psAux, "%%" + p.getDescricao().toUpperCase()
							+ "%%");
				}
				if (p.getGrupo() != null && !"".equals(p.getGrupo())) {
					psAux++;
					ps.setString(psAux, "%%" + p.getGrupo().toUpperCase()
							+ "%%");
				}
				if (p.getGrupoDesc() != null && !"".equals(p.getGrupoDesc())) {
					psAux++;
					ps.setString(psAux, "%%" + p.getGrupoDesc().toUpperCase()
							+ "%%");
				}
				if (p.getFilial() != null && !"".equals(p.getFilial())) {
					psAux++;
					ps.setString(psAux, p.getFilial());
				}
				rs = ps.executeQuery();
				while (rs.next()) {
					produto = (P) new ProdutoBean();
					produto.setCodigo(rs.getString("B1_COD"));
					produto.setDescricao(rs.getString("B1_DESC"));
					produto.setUnidMedida(rs.getString("B1_UM"));
					produto.setGrupo(rs.getString("B1_GRUPO"));
					produto.setGrupoDesc(rs.getString("BM_DESC"));
					produto.setGrupoPai(rs.getString("BM_GRUREL"));
					produto.setLeadTime(rs.getInt("B1_PE"));
					produto.setItemPosicao(rs.getString("Z2REC"));
					listaProd.add(produto);
				}
				return listaProd;
			}

			return listaProd;

		} catch (Exception e) {
			throw e;
		} finally {
			super.fecharRecursos(ps, rs);
		}
	}

	@SuppressWarnings("unchecked")
	public List<P> buscaProdutos(Map<String, String> param) throws Exception {
		ProdutoBean produto;
		List<ProdutoBean> listaProd = new ArrayList<ProdutoBean>();
		int psAux = 0;
		try {
			conn = GerenciadorConexao.getConexao();
			query = SQLConfiguracao.getInstance().getValor("localiza_produtos");
			if (param.get("CODIGO") != null) {
				query += " AND UPPER(B1_COD) LIKE ?";
			}
			if (param.get("NOME") != null) {
				query += " AND UPPER(B1_DESC) LIKE ?";
			}

			query += " LEFT JOIN ZZ2010 ON ZZ2_PRODUT = B1_COD AND ZZ2010.D_E_L_E_T_ <> '*'";

			ps = conn.prepareStatement(query);

			if (param.get("CODIGO") != null && !"".equals(param.get("CODIGO"))) {
				psAux++;
				ps.setString(psAux, param.get("CODIGO").toUpperCase().trim()
						+ "%%");
			}
			if (param.get("NOME") != null && !"".equals(param.get("NOME"))) {
				psAux++;
				ps.setString(psAux, "%%"
						+ param.get("NOME").toUpperCase().trim() + "%%");
			}
			rs = ps.executeQuery();
			while (rs.next()) {
				produto = new ProdutoBean();
				produto.setCodigo(rs.getString("B1_COD"));
				produto.setDescricao(rs.getString("B1_DESC"));
				produto.setUnidMedida(rs.getString("B1_UM"));
				produto.setGrupo(rs.getString("B1_GRUPO"));
				produto.setGrupoDesc(rs.getString("BM_DESC"));
				produto.setGrupoPai(rs.getString("BM_GRUREL"));
				produto.setLeadTime(rs.getInt("B1_PE"));
				listaProd.add(produto);
			}

		} catch (Exception e) {
			throw e;
		} finally {
			super.fecharRecursos(ps, rs);

		}

		return (List<P>) listaProd;
	}

	@Override
	public ProdutoBean verificaProduto(String cod, String filial)
			throws Exception {
		conn = null;
		ps = null;
		rs = null;
		query = null;
		ResultSet rs2;
		PreparedStatement ps2;

		ProdutoBean produto = null;
		try {
			conn = GerenciadorConexao.getConexao();
			query = SQLConfiguracao.getInstance().getValor("localiza_produto");
			ps = conn.prepareStatement(query);
			ps.setString(1, cod.trim());
			rs = ps.executeQuery();
			int leadTime;
			if (rs.next()) {
				produto = new ProdutoBean();
				produto.setCodigo(rs.getString("B1_COD").trim());
				produto.setDescricao(rs.getString("B1_DESC").trim());
				produto.setUnidMedida(rs.getString("B1_UM"));
				produto.setSegUniMedida(rs.getString("B1_SEGUM").trim());
				produto.setGrupo(rs.getString("B1_GRUPO"));
				produto.setGrupoPai(rs.getString("BM_GRUREL"));
				query = SQLConfiguracao.getInstance().getValor(
						"localiza_arm_parametro");
				ps2 = conn.prepareStatement(query);
				ps2.setString(1, filial);
				ps2.setString(2, produto.getCodigo().trim());
				rs2 = ps2.executeQuery();
				if (rs2.next()) {
					if (!"".equals(rs2.getString("ZPR_LOCPAD").trim())) {
						produto.setLocal(rs2.getString("ZPR_LOCPAD"));
					} else {
						produto.setLocal(rs.getString("B1_LOCPAD"));
					}
				} else {
					produto.setLocal(rs.getString("B1_LOCPAD"));
				}
				leadTime = rs.getInt("B1_PE");
				query = SQLConfiguracao.getInstance().getValor(
						"localiza_leadtimeBz");
				ps = conn.prepareStatement(query);
				ps.setString(1, produto.getCodigo().trim());
				ps.setString(2, filial.trim());
				rs = ps.executeQuery();
				if (rs.next()) {
					produto.setLeadTime(rs.getInt("BZ_PE"));
				} else {
					produto.setLeadTime(leadTime);
				}
			}
			return produto;
		} catch (Exception e) {
			throw e;
		} finally {
			super.fecharRecursos(ps, rs);
		}

	}

	@Override
	public boolean verificaLocal(String filial, String cod) throws Exception {
		conn = null;
		ps = null;
		rs = null;
		query = null;
		boolean existe = false;
		try {
			conn = GerenciadorConexao.getConexao();
			query = SQLConfiguracao.getInstance().getValor("localiza_local");
			ps = conn.prepareStatement(query);
			// ps.setString(1, filial.trim()); ZAL_FILIAL = ? RETIRADO CLAUSULA
			// DE FILIAL, POIS EXISTEM PRODUTOS QUE NAO MOVIMENTAM ESTOQUE E
			// PORTANTO NAO POSSUEM ARMAZEM
			ps.setString(1, cod.trim().toUpperCase());
			rs = ps.executeQuery();
			if (rs.next()) {
				existe = true;
			}
			return existe;
		} catch (Exception e) {
			throw e;
		} finally {
			super.fecharRecursos(ps, rs);
		}
	}

	@Override
	public boolean verificaOrdemProducao(String filial, String cod)
			throws Exception {
		conn = null;
		ps = null;
		rs = null;
		query = null;
		boolean existe = false;
		try {
			conn = GerenciadorConexao.getConexao();
			query = SQLConfiguracao.getInstance().getValor("localiza_ordem");
			ps = conn.prepareStatement(query);
			ps.setString(1, filial);
			ps.setString(2, cod);
			rs = ps.executeQuery();
			if (rs.next()) {
				existe = true;
			}
			return existe;
		} catch (Exception e) {
			throw e;
		} finally {
			super.fecharRecursos(ps, rs);
		}
	}

	public SortedMap<String, String> buscaEstoqueProduto(
			SolicitacaoBean solicitacao) throws Exception {

		SortedMap<String, String> armazemEstoque = new TreeMap<String, String>();
		try {

			conn = GerenciadorConexao.getConexao();
			query = SQLConfiguracao.getInstance().getValor(
					"localiza_produto_estoque");
			ps = conn.prepareStatement(query);
			ps.setString(1, solicitacao.getItensSolicitacao().get(0)
					.getCodigo());
			rs = ps.executeQuery();
			while (rs.next()) {
				armazemEstoque.put(
						rs.getString("B2_FILIAL") + rs.getString("B2_LOCAL"),
						rs.getDouble("B2_QATU") + "");
			}

		} catch (Exception e) {
			throw e;
		}

		return armazemEstoque;
	}

	public List<ProdutoBean> buscaAnaliseProdutoHistoricoPedido(
			final ProdutoBean produto) throws Exception {

		List<ProdutoBean> produtos = new ArrayList<ProdutoBean>();
		ProdutoBean prod = null;
		ResultSet rs2 = null;
		String query2 = null;
		String query3 = null;
		try {
			conn = GerenciadorConexao.getConexao();
			query = SQLConfiguracao.getInstance().getValor(
					"localiza_saldo_produto");
			query2 = SQLConfiguracao.getInstance().getValor(
					"localiza_produto_ponto_pedido");
			query3 = SQLConfiguracao.getInstance().getValor(
					"localiza_ultimo_preco_pedido");
			ps = conn.prepareStatement(query);
			ps.setString(1, produto.getCodigo());
			rs = ps.executeQuery();
			while (rs.next()) {
				prod = new ProdutoBean();
				prod.setCodigo(rs.getString("B2_COD"));
				prod.setDescricao(rs.getString("B1_DESC"));
				prod.setUnidMedida(rs.getString("B1_UM"));
				prod.setSaldoAtual(rs.getDouble("TOTAL"));
				prod.setFilial(rs.getString("B2_FILIAL"));
				ps = conn.prepareStatement(query2);
				ps.setString(1, rs.getString("B2_COD"));
				ps.setString(2, rs.getString("B2_FILIAL"));
				rs2 = ps.executeQuery();
				if (rs2.next()) {
					prod.setPontoPedido(rs2.getDouble("BZ_EMIN"));
					prod.setLoteEconomico(rs2.getDouble("BZ_QE"));
				} else {
					prod.setPontoPedido(0.00);
					prod.setLoteEconomico(0.00);
				}
				ps = conn.prepareStatement(query3);
				ps.setString(1, rs.getString("B2_FILIAL"));
				ps.setString(2, rs.getString("B2_COD"));
				rs2 = ps.executeQuery();
				if (rs2.next()) {
					prod.setPreco(rs2.getDouble("C7_PRECO"));
				} else {
					prod.setPreco(0.00);
				}
				produtos.add(prod);
			}

		} catch (Exception e) {
			throw e;
		} finally {
			rs2.close();
			super.fecharRecursos(ps, rs);
		}

		return produtos;

	}

	public Map<Integer, Double> buscaConsumoProduto(ProdutoBean produto,
			List<Integer> meses, List<Integer> anos) throws Exception {

		Map<Integer, Double> consumos = new HashMap<Integer, Double>();

		try {
			conn = GerenciadorConexao.getConexao();
			int i = 0;
			int j = 0;
			query = "SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL " + "FROM SD3010 "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "' AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*'  "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010 "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL  SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010  "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++)
					+ "AND SD3010.D_E_L_E_T_ <> '*' "
					+ "UNION ALL SELECT ISNULL(SUM(D3_QUANT),0) AS TOTAL "
					+ "FROM SD3010 "
					+ "WHERE D3_FILIAL = '"
					+ produto.getFilial()
					+ "'"
					+ "AND D3_COD = '"
					+ produto.getCodigo().trim()
					+ "'"
					+ "AND D3_TM >= 501 "
					+ "AND D3_TM < 999 "
					+ "AND MONTH(D3_EMISSAO) = "
					+ (meses.get(i++) + 1)
					+ "AND YEAR(D3_EMISSAO) = "
					+ anos.get(j++) + "AND SD3010.D_E_L_E_T_ <> '*'  ";
			ps = conn.prepareStatement(query);
			rs = ps.executeQuery();
			i = 11;
			while (rs.next()) {
				consumos.put(meses.get(i--), rs.getDouble("TOTAL"));
			}
		} catch (Exception e) {
			throw e;
		} finally {
			super.fecharRecursos(ps, rs);
		}

		return consumos;
	}

	@SuppressWarnings("unchecked")
	public List<P> buscaProdutosPedido(Map<String, String> param)
			throws Exception {
		List<ProdutoBean> listaProdutos = new ArrayList<ProdutoBean>();
		ProdutoBean produto = null;
		TabelaPrecoServico<TabelaPrecoBean> tabelaServico = new TabelaPrecoServico<TabelaPrecoBean>();
		try {
			conn = GerenciadorConexao.getConexao();
			query = SQLConfiguracao.getInstance().getValor(
					"localiza_produtos_pedido");
			ps = conn.prepareStatement(query);
			ps.setString(1, param.get("FILIAL"));
			ps.setString(2, param.get("NUMPED"));
			rs = ps.executeQuery();
			while (rs.next()) {
				produto = new ProdutoBean();
				produto.setCodigo(rs.getString("C7_PRODUTO").trim());
				produto.setDescricao(rs.getString("C7_DESCRI").trim());
				produto.setItemPosicao(rs.getString("C7_ITEM").trim());

				produto.setUnidMedida(rs.getString("C7_UM").trim());
				produto.setQuantidade(rs.getDouble("C7_QUANT"));
				produto.setQtdeAtendida(rs.getDouble("C7_QUJE"));
				produto.setIpi(rs.getDouble("C7_IPI"));
				produto.setIcms(rs.getDouble("C7_PICM"));
				produto.setNecessidade(Ferramentas.formataData(
						rs.getString("C7_DATPRF"), "yyyyMMdd"));
				produto.setPreco(rs.getDouble("C7_PRECO"));
				produto.setObservacao(rs.getString("C7_OBS").trim());
				produto.setCentroCusto(new CentroCustoBean("", rs
						.getString("C7_CC"), ""));
				produto.setLocal(rs.getString("C7_LOCAL"));
				produto = tabelaServico.buscaPrecoItensTabela(
						new FornecedorBean(param.get("FORNE"), param
								.get("LOJAFOR"), ""), produto);
				listaProdutos.add(produto);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			super.fecharRecursos(ps, rs);
		}
		return (List<P>) listaProdutos;
	}
}
